package com.sasis.webapp.task;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletContext;

import org.acegisecurity.providers.AuthenticationProvider;
import org.acegisecurity.providers.ProviderManager;
import org.acegisecurity.providers.encoding.Md5PasswordEncoder;
import org.acegisecurity.providers.encoding.PasswordEncoder;
import org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import com.sasis.Constants;
import com.sasis.service.LookupManager;

public class InitializeConfigTask implements StartupTask {

	private static final Log log = LogFactory
			.getLog(InitializeConfigTask.class);
	
	private LookupManager lookupManager;
	
	private ProviderManager authenticationManager;
	
	private PasswordEncoder passwordEncoder;
	
	public void setLookupManager(LookupManager lookupManager) {
		this.lookupManager = lookupManager;
	}
	
	public void setAuthenticationManager(ProviderManager authenticationManager) {
		this.authenticationManager = authenticationManager;
	}
	
	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
		this.passwordEncoder = passwordEncoder;
	}
	
	public void doTask(ServletContext context) {
		if (log.isDebugEnabled()) {
			log.debug("initializing context...");
		}

		// Orion starts Servlets before Listeners, so check if the config
		// object already exists
		Map config = (HashMap) context.getAttribute(Constants.CONFIG);

		if (config == null) {
			config = new HashMap();
		}

		if (context.getInitParameter(Constants.CSS_THEME) != null) {
			config.put(Constants.CSS_THEME, context
					.getInitParameter(Constants.CSS_THEME));
		}

		boolean encryptPassword = false;
		try {
			for (Iterator it = authenticationManager.getProviders().iterator(); it.hasNext();) {
				AuthenticationProvider p = (AuthenticationProvider) it.next();
				if (p instanceof RememberMeAuthenticationProvider) {
					config.put("rememberMeEnabled", Boolean.TRUE);
				}
			}

			if (passwordEncoder != null) {
				encryptPassword = true;
				config.put(Constants.ENCRYPT_PASSWORD, Boolean.TRUE);
				String algorithm = "SHA";
				if (passwordEncoder instanceof Md5PasswordEncoder) {
					algorithm = "MD5";
				}
				config.put(Constants.ENC_ALGORITHM, algorithm);
			}
		} catch (NoSuchBeanDefinitionException n) {
			// ignore, should only happen when testing
		}

		context.setAttribute(Constants.CONFIG, config);

		// output the retrieved values for the Init and Context Parameters
		if (log.isDebugEnabled()) {
			log
					.debug("Remember Me Enabled? "
							+ config.get("rememberMeEnabled"));
			log.debug("Encrypt Passwords? " + encryptPassword);
			if (encryptPassword) {
				log.debug("Encryption Algorithm: "
						+ config.get(Constants.ENC_ALGORITHM));
			}
			log.debug("Populating drop-downs...");
		}

		context.setAttribute(Constants.AVAILABLE_ROLES, lookupManager.getAllRoles());
		if (log.isDebugEnabled()) {
			log.debug("Drop-down initialization complete [OK]");
		}
	}

	public boolean isAsynchronous() {
		return false;
	}

}
